﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using System.IO.Ports;
using System.Configuration;
using SerialPortHelperLib;
using XChip_Common;
using XChipTool.Enties;
using BinAnalysisHelp;

namespace XChipTool
{
    public partial class XChip_TopReg : DevExpress.XtraEditors.XtraForm
    {
        public SerialPort sPortTemp;
        private addressregisterManager aBll;
        // 定义一个静态变量来保存类的实例
        private static XChip_TopReg _xChip_TopReg;
        // 定义一个标识确保线程同步
        private static readonly object locker = new object();
        private List<addressregister> XChipTopReg;
        private bool isRead = false;
        //记录是否使用USB设备读写
        public bool IsUsbOpen = false;
        //记录是否使用I2C设备读写
        public bool m_open = false;
        List<string> listFiltration = new List<string> { "cfa", "cfa_enh", "ygamma_clk", "ygamma", "snrtop", "snr", "ynrtop", "ynr", "ynr_enh", "cfa_enh" };
        public XChip_TopReg()
        {
            InitializeComponent();
        }
        public XChip_TopReg(SerialPort _sPortTemp, addressregisterManager _aBll)
        {
            sPortTemp = _sPortTemp;
            aBll = _aBll;
            XChipTopReg = aBll.GetList(c => c.ChipType == ConfigurationManager.AppSettings["xc151_ChipType"] && (c.Classify == "TopReg" || c.Classify == "Common"));

            InitializeComponent();
        }

        public static XChip_TopReg GetInstance(SerialPort _sPortTemp, addressregisterManager _aBll)
        {
            // 当第一个线程运行到这里时，此时会对locker对象 "加锁"，
            // 当第二个线程运行该方法时，首先检测到locker对象为"加锁"状态，该线程就会挂起等待第一个线程解锁
            // lock语句运行完之后（即线程运行完之后）会对该对象"解锁"
            // 双重锁定只需要一句判断就可以了
            if (_xChip_TopReg == null || _xChip_TopReg.IsDisposed)
            {
                lock (locker)
                {
                    // 如果类的实例不存在则创建，否则直接返回
                    if (_xChip_TopReg == null || _xChip_TopReg.IsDisposed)
                    {
                        _xChip_TopReg = new XChip_TopReg(_sPortTemp, _aBll);
                    }
                }
            }
            return _xChip_TopReg;
        }

        public static XChip_TopReg GetInstance()
        {
            // 当第一个线程运行到这里时，此时会对locker对象 "加锁"，
            // 当第二个线程运行该方法时，首先检测到locker对象为"加锁"状态，该线程就会挂起等待第一个线程解锁
            // lock语句运行完之后（即线程运行完之后）会对该对象"解锁"
            // 双重锁定只需要一句判断就可以了
            if (_xChip_TopReg == null || _xChip_TopReg.IsDisposed)
            {
                lock (locker)
                {
                    // 如果类的实例不存在则创建，否则直接返回
                    if (_xChip_TopReg == null || _xChip_TopReg.IsDisposed)
                    {
                        _xChip_TopReg = new XChip_TopReg();
                    }
                }
            }
            return _xChip_TopReg; 
        }

        private void simpleButton5_Click(object sender, EventArgs e)
        {
            if (!sPortTemp.IsOpen && !IsUsbOpen && !m_open)
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("可用端口未打开");
                return;
            }
            isRead = true;
            WaitBefore.Start("读取中", "正在加载中", 10);
            List<string> NameList = new List<string>();
            for (int i = 0; i < XChipTopReg.Count; i++)
            {
                var type = AppHelper.NameTypeToString(XChipTopReg[i].NameType.ToLower());
                //加上单选框的_en
                if (XChipTopReg[i].ControlType == "1")
                {
                    type = XChipTopReg[i].NameType;
                }
                var col = Controls_Find(type);

                foreach (var item in col)
                {
                    if (NameList.Exists(c => c == (type)))
                    {
                        continue;
                    }
                    else
                    {
                        if (item is TextEdit)
                        {
                            var nList = XChipTopReg.Where(c => c.NameType.ToLower().Contains(item.Name.ToString().ToLower()) && c.ControlType == "0").ToList();
                            if (nList.Count == 0)
                            {
                                nList = XChipTopReg.Where(c => c.NameType.ToLower().Contains(item.Name.ToString().ToLower()) && c.ControlType == "0").ToList();
                            }
                            if (nList.Count == 1)
                            {
                                var Val = SerialSend.ReadRegister(Convert.ToUInt32(nList[0].Address, 16), sPortTemp).ToString("X");
                                item.Text = BitsHelp.GetBitsToUint(nList[0].Bits, nList[0].Hex, Val).ToString("X");
                            }
                            else
                            {
                                string Val = string.Empty;
                                //这里默认为是有多个寄存器  一个文本框的情况进行处理
                                if (nList.Exists(c => c.NameType.ToLower().Contains("_h")))
                                {
                                    Val += SerialSend.ReadRegister(Convert.ToUInt32(nList.Find(c => c.NameType.ToLower().Contains("_h")).Address, 16), sPortTemp).ToString("X2");
                                }
                                if (nList.Exists(c => c.NameType.ToLower().Contains("_m0")))
                                {
                                    Val += SerialSend.ReadRegister(Convert.ToUInt32(nList.Find(c => c.NameType.ToLower().Contains("_m0")).Address, 16), sPortTemp).ToString("X2");
                                }
                                if (nList.Exists(c => c.NameType.ToLower().Substring(c.NameType.Length - 2).Contains("_l")))
                                {
                                    Val += SerialSend.ReadRegister(Convert.ToUInt32(nList.Find(c => c.NameType.ToLower().Substring(c.NameType.Length - 2).Contains("_l")).Address, 16), sPortTemp).ToString("X2");
                                }
                                if (string.IsNullOrEmpty(Val))
                                {
                                    nList = XChipTopReg.Where(c => c.NameType.ToLower() == (item.Name.ToString().ToLower()) && c.ControlType == "0").ToList();
                                    if (nList.Count() == 1)
                                    {
                                        Val += SerialSend.ReadRegister(Convert.ToUInt32(nList[0].Address, 16), sPortTemp).ToString("X");
                                    }
                                }
                                item.Text = Val;
                            }
                        }
                        else if (item is CheckEdit)
                        {
                            var nList = XChipTopReg.Where(c => c.NameType.ToLower().Contains(item.Name.ToString().ToLower()) && c.ControlType == "1").ToList();
                            if (nList.Count == 1)
                            {
                                var Val = SerialSend.ReadRegister(Convert.ToUInt32(nList[0].Address, 16), sPortTemp).ToString("X");
                                (item as CheckEdit).Checked = BitsHelp.GetBitsCheckedToBool(nList[0].Bits, nList[0].Hex, Val) == 0;
                            }
                        }
                    }
                }
                NameList.Add(type);
            }

            #region 部分名称重复的寄存器
            cfa_en.Checked = (GetTopRegister("cfa_en") & 0x1) == 0x1;
            cfa_enh_en.Checked = (GetTopRegister("cfa_enh_en") & 0x1) == 0x1;

            ygamma_clk_en.Checked = (GetTopRegister("ygamma_clk_en") & 0x1) == 0x1;
            ygamma_en.Checked = (GetTopRegister("ygamma_en") & 0x8) == 0x8;

            snrtop_en.Checked = (GetTopRegister("snrtop_en") & 0x2) == 0x2;
            snr_en.Checked = (GetTopRegister("snr_en") & 0x40) == 0x40;

            ynrtop_en.Checked = (GetTopRegister("ynrtop_en") & 0x4) == 0x4;
            ynr_en.Checked = (GetTopRegister("ynr_en") & 0x1) == 0x1;
            ynr_enh_en.Checked = (GetTopRegister("ynr_enh_en") & 0x2) == 0x2;

            cfa_enh_en.Checked = (GetTopRegister("cfa_enh_en") & 0x1) == 0x1;
            #endregion

            isRead = false;
            WaitBefore.Close();
        }
        private Control[] Controls_Find(string str)
        {
            //var t =   this.Controls.Find(type, true);
            List<Control> listc = new List<Control>();
            System.Reflection.FieldInfo[] fieldInfo = this.GetType().GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            for (int i = 0; i < fieldInfo.Length; i++)
            {
                if (fieldInfo[i].Name.ToLower().Contains(str.ToLower()))
                {
                    listc.AddRange(this.Controls.Find(fieldInfo[i].Name, true));
                    break;
                }
            }
            return listc.ToArray();
        }

        private void cfa_en_CheckedChanged(object sender, EventArgs e)
        {
            var chk = sender as CheckEdit;
            if (isRead) return;
            if (XChipTopReg.Exists(c => c.NameType.ToLower() == (chk.Name).ToLower()))
            {
                var model = XChipTopReg.Find(c => c.NameType.ToLower() == (chk.Name).ToLower());
                var Add = SerialSend.ReadRegister(Convert.ToUInt32(model.Address, 16), sPortTemp);
                var Val = BitsHelp.SetBitsCheckedToUint(model.Bits, model.Hex, Add.ToString("X2"), chk.Checked);
                SetTopRegRegister(model, Val);
            }
        }

        private void SetTopRegRegister(addressregister model, ulong add, bool isCheck = true)
        {
            if (isRead) return;
            if (IsUsbOpen)
            {

                if (null != BinHelp.usbList)
                {
                    uint pVule = 0x0;
                    var isbool = false;
                    if (IntPtr.Size == 8)
                    {
                        isbool = XChipUSB.UsbRegisterRead64(BinHelp.CurrentSize, ref pVule, true);
                        SerialSend.Sendser("R:0x" + (BinHelp.CurrentSize).ToString("X2"), pVule.ToString("X2"));


                    }
                    else
                    {
                        isbool = XChipUSB.UsbRegisterRead86(BinHelp.CurrentSize, ref pVule, true);
                        SerialSend.Sendser("R:0x" + (BinHelp.CurrentSize).ToString("X2"), pVule.ToString("X2"));
                    }
                    var chang = (int)(pVule >> 16); // 使用右移16位操作来获取高16位  
                    var kuang = (int)(pVule & 0xFFFF); // 使用位与操作来获取低16位  


                    BinHelp.SstBinUsbUpdateData(ref BinHelp.BinList, model.Address, add.ToString("X"), chang, kuang);
                }
            }
            else if (m_open)
            {

            }
            else
            {

                if (null != BinHelp.lspList)
                { //编写Bin更新数据
                    var temp = SerialSend.ReadRegister(BinHelp.BootSettingIdx, sPortTemp);
                    BinHelp.SetBinUpdateData(ref BinHelp.BinList, model.Address, add.ToString("X"), (uint)temp);
                }
            }

            SerialSend.WriteRegister(Convert.ToUInt32(model.Address, 16), add, sPortTemp);
        }

        private long GetTopRegister(string nameType)
        {
            if (XChipTopReg.Where(c => c.NameType.ToLower() == nameType.ToLower()).Count() > 0)
                return SerialSend.ReadRegister(Convert.ToUInt32(XChipTopReg.Where(c => c.NameType.ToLower() == nameType.ToLower()).First().Address, 16), sPortTemp);
            else { DevExpress.XtraEditors.XtraMessageBox.Show($"未找到{nameType}"); return -1; }
        }
    }
}